package calendar.model;

import calendar.commands.Authorize;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.Lists;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.calendar.model.Calendar;
import design.patterns.state.State;
import model.Model;

import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.List;

import static java.lang.System.getProperty;

/**
 * @author Yaniv Inbar
 */
public class CalendarModel extends Model {

    /**
     * Be sure to specify the name of your application. If the application name is {@code null} or
     * blank, the application will log a warning. Suggested format is "MyCompany-ProductName/1.0".
     */
    public static final String APPLICATION_NAME = "system-tray-notifier";

    /**
     * Directory to store user credentials.
     */
    private static final File DATA_STORE_DIR =
            new File(getProperty("user.home"), ".store/calendar_sample");

    public static final Calendars CALENDARS = new Calendars();
    public static final EventEntity EVENTS = new EventEntity();

    public static final State CREDENTIAL_ACCEPTED = new State("Credential accepted");

    /**
     * Global instance of the {@link com.google.api.client.util.store.DataStoreFactory}. The best practice is to make it a single
     * globally shared instance across your application.
     */
    public static final FileDataStoreFactory DATA_STORE_FACTORY;

    /**
     * Global instance of the HTTP transport.
     */
    public static final HttpTransport HTTP_TRANSPORT;

    static {
        try {
            HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();

            // initialize the data store factory
            DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
        } catch (GeneralSecurityException | IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Global instance of the JSON factory.
     */
    public static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

    public static final List<Calendar> addedCalendarsUsingBatch = Lists.newArrayList();

    public final static CalendarModel INSTANCE = new CalendarModel();


    private CalendarModel() {
        super(CALENDARS, EVENTS);

        try {
            // authorization
            new Authorize()
                    .onFinished((o, arg) -> setState(CREDENTIAL_ACCEPTED, arg))
                    .execute();
        } catch (Throwable t) {
            t.printStackTrace();
            throw new RuntimeException(t);
        }
    }
}